package com.gxty.gat1400.utils

import com.gxty.gat1400.domain.DigestAuthInfo
import java.security.MessageDigest
import java.security.NoSuchAlgorithmException
import java.util.*

object AuthDigestUtil {
    /**
     * 根据当前时间戳生成一个随机字符串
     */
    fun generateNonce(): String? {
        val s = (System.currentTimeMillis() + Random().nextInt()).toString()
        return try {
            val messageDigest = MessageDigest.getInstance("md5")
            val digest = messageDigest.digest(s.toByteArray())
            Base64.getEncoder().encodeToString(digest)
        } catch (e: NoSuchAlgorithmException) {
            throw RuntimeException()
        }
    }

    fun MD5(inStr: String): String {
        val md5 = try {
            MessageDigest.getInstance("MD5")
        } catch (e: Exception) {
            e.printStackTrace()
            return ""
        }
        val charArray = inStr.toCharArray()
        val byteArray = ByteArray(charArray.size)
        for (i in charArray.indices) {
            byteArray[i] = charArray[i].code.toByte()
        }
        val md5Bytes = md5.digest(byteArray)
        val hexValue = StringBuffer()
        for (i in md5Bytes.indices) {
            val value = md5Bytes[i].toInt() and 0xff
            if (value < 16) hexValue.append("0")
            hexValue.append(Integer.toHexString(value))
        }
        return hexValue.toString()
    }

    /**
     * 该方法用于将 Authorization 请求头的内容封装成一个对象。
     *
     * Authorization 请求头的内容为：
     * Digest username="aaa", realm="no auth", nonce="b2b74be03ff44e1884ba0645bb961b53",
     * uri="/BootDemo/login", response="90aff948e6f2207d69ecedc5d39f6192", qop=auth,
     * nc=00000002, cnonce="eb73c2c68543faaa"
     */
    fun getAuthInfoObject(_authStr: String): DigestAuthInfo {
        var authStr = _authStr
        if (authStr.lowercase(Locale.getDefault()).indexOf("digest") >= 0) {
            // 截掉前缀 Digest
            authStr = authStr.substring(6)
        }
        // 将双引号去掉
        authStr = authStr.replace("\"", "")

        val authInfo = DigestAuthInfo()
        val authArray = authStr.split(",").toTypedArray()

        for (i in authArray.indices) {
            val auth = authArray[i]
            val key = auth.substring(0, auth.indexOf("=")).trim()
            val value = auth.substring(auth.indexOf("=") + 1).trim()
            when (key) {
                "username" -> authInfo.username = value
                "realm" -> authInfo.realm = value
                "nonce" -> authInfo.nonce = value
                "uri" -> authInfo.uri = value
                "response" -> authInfo.response = value
                "qop" -> authInfo.qop = value
                "nc" -> authInfo.nc = value
                "cnonce" -> authInfo.cnonce = value
            }
        }
        return authInfo
    }
}